package com.wl.aop.junit;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class JunitRunner {
    public static void main(String[] args) throws Exception {
        JunitRunner runner = new JunitRunner();
        runner.runTest(MathBizTest.class);
    }

    public void runTest(Class testClass) throws Exception{
        //创建测试对象
        //相当于 new XXX()
        Object tester = testClass.newInstance();

        List<Method> befores = new ArrayList<>();
        List<Method> afters = new ArrayList<>();
        List<Method> tests = new ArrayList<>();

        Method[] methods = testClass.getMethods();
        for (Method method : methods) {
            if (method.getAnnotation(Before.class)!=null) {
                befores.add(method);

            }if (method.getAnnotation(After.class)!=null) {
                afters.add(method);

            }if (method.getAnnotation(Test.class)!=null) {
                tests.add(method);
            }
        }

        // TODO 扩展： 对测试方法排序

        for (Method test : tests) {
            for (Method before : befores) {
                before.invoke(tester);
            }
             try{
                 test.invoke(tester);
             }catch(InvocationTargetException e){
                 //获取异常原因
                 Throwable cause = e.getCause();
                 System.out.println("方法业务异常 "+ cause);
            }catch (AssertException e){
                 System.out.println("测试结果错误 ");
             }
            //测试方法执行到这里，表示测试通过
            for (Method after : afters) {
                after.invoke(tester);
            }
        }

        //TODO 请统计正确得测试结果数据量，异常数据，错误得数量
        System.out.println("测试结果");
    }
}

@Retention(RetentionPolicy.RUNTIME)
@interface Test{
    int value();
}

@interface Before{

}

@interface After{

}

class Assert{
    public static void assertEquals(Object aspect,Object act){
        if(!aspect.equals(act)){
            String s = String.format("期待结果是：%s，实际结果是；%s", aspect, act);
            throw new AssertException(s);
        }
    }
}

class AssertException extends RuntimeException{

    public AssertException(String message) {
        super(message);
    }
}
